<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <title>列表</title>
    <meta name="renderer" content="webkit">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport"
        content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
    <link rel="stylesheet" href="/layui/css/layui.css" media="all">
    <link rel="stylesheet" href="/src/css/main.css" media="all">
    <style>
        /* .layui-tree-entry {
            padding-left: 20px;
        }

        .layui-tree li ul {
            margin-left: 20px;
        } */
        /* 添加树形样式 */
        .layui-tree li {
            position: relative;
        }

        .layui-tree li>.layui-tree-entry {
            padding-left: calc(20px * var(--depth));
            /* 根据depth动态缩进 */
        }

        .layui-tree .disabled-node {
            color: #c0c4cc;
            cursor: not-allowed;
        }
    </style>
</head>

<body>
    <div id="layui-body-content" class="layui-fluid">
        <div class="layui-card">
            <div class="layui-card-body">
                <form class="layui-form layui-form-pane">
                    <div class="gridAuto">
                        <div class="layui-form-item">
                            <label class="layui-form-label">角色名称</label>
                            <div class="layui-input-block">
                                <div class="layui-input-wrap">
                                    <input type="text" name="name" id="name" placeholder="请输入角色名称" lay-affix="clear"
                                        autocomplete="off" class="layui-input">
                                </div>
                            </div>
                        </div>
                    </div>
                    <div class="layui-btn-container selectFormBox">

                        <button class="layui-btn layuiadmin-btn-role-list  layui-btn-sm" type="button"
                            lay-on="Yjsearch">
                            <i class="layui-icon layui-icon-search layuiadmin-button-btn"></i>查询
                        </button>
                        <button type="reset" class="layui-btn layui-btn-primary layui-btn-sm">
                            <i class="layui-icon layui-icon-fonts-clear"></i>清空
                        </button>
                    </div>
                </form>
                <div style="padding-left: 10px; padding-bottom: 10px; padding-top: 0px;" id="divpath">
                    <a id="0" data-type="next" class="layuiadmin-btn-role-list layui-a-tips">所有角色>></a>
                </div>
                <table id="LAY-app-role-list" lay-filter="LAY-app-role-list"></table>
                <input type="hidden" id="pid" />
                <input type="hidden" id="parent_path" />
                <script type="text/html" id="ID-table-status-switch">
                    <input type="checkbox" name="status" value="{{= d.id }}" disabled title="启用|禁用" lay-skin="switch" lay-filter="demo-templet-status" {{= d.status == '0' ? "checked" : "" }}>
                  </script>
                <script type="text/html" id="tableoption">
                    <a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="next"><i class="layui-icon layui-icon-edit"></i>下一级</a>
                </script>
                <script type="text/html" id="LAY-app-role-toolbar">
                    {{#  if(!d.haschildren){ }}
                      <a class="layui-btn layui-btn-xs" lay-event="permission"><i class="layui-icon layui-icon-vercode"></i>权限分配</a>
                    {{#  } else { }}
                      <a class="layui-btn layui-btn-xs layui-btn-disabled"><i class="layui-icon layui-icon-vercode"></i>权限分配</a>
                    {{#  } }}
                  </script>
            </div>
        </div>
    </div>
    <script type="text/html" id="permissionTpl">
        <div class="layui-fluid" style="padding: 20px;height: 100%;">
            <div class="layui-row" style="height: 100%;">
              <div class="layui-col-md12" style="height: 100%;">
                <div id="permissionTree" style="height: 100%;overflow-y: auto;"></div>
              </div>
            </div>
          <div class="layui-form-item layui-hide">
            <div class="layui-input-block">
              <button class="layui-btn" lay-submit lay-filter="submitPermission">提交</button>
            </div>
          </div>
        </div>
      </script>

    <script src="/layui/layui.js"></script>
    <script>
        layui.config({
            base: '/src/'
        }).use('index', function () {
            var table = layui.table,
                $ = layui.$,
                $body = $('body'),
                main = layui.main,
                dropdown = layui.dropdown,
                form = layui.form,
                form2 = top.layui.form,
                util = layui.util,
                layer = layui.layer,
                layer2 = top.layui.layer,
                tree = layui.tree,
                admin = layui.admin;
            // 角色
            let breadcrumb = [{ id: 0, name: '所有角色', path: '0' }];
            function updateBreadcrumb() {
                let html = '';
                breadcrumb.forEach((item, index) => {
                    if (index > 0) html += ' >> ';
                    html += `<a class="layuiadmin-btn-role-list layui-a-tips" 
                    data-id="${item.id}" 
                    data-index="${index}"
                    data-path="${item.path}" 
                    style="cursor: pointer;">${item.name}</a>`;
                });
                $('#divpath').html(html);
            }
            // 点击路径导航时触发
            $('#divpath').on('click', 'a', function () {
                const index = $(this).data('index');
                const item = breadcrumb[index];

                // 截断面包屑到当前点击的层级
                breadcrumb = breadcrumb.slice(0, index + 1);

                // 更新 pid 和 parent_path
                pid = item.id;
                parent_path = item.path;

                // 同步到隐藏字段
                $("#pid").val(pid);
                $("#parent_path").val(parent_path);

                // 重新加载表格
                table.reload('LAY-app-role-list', { where: { pid: pid } });

                // 更新面包屑显示
                updateBreadcrumb();

            });
            var pid = 0;
            var parent_path = "0"; // 初始路径为根节点
            $("#parent_path").val(parent_path);
            updateBreadcrumb(); // 初始化路径显示
            table.render({
                elem: '#LAY-app-role-list',
                url: admin.getUrl('sysrole/GetRoleList'),
                where: {
                    pid: pid,
                },
                cols: [[
                    {
                        type: 'numbers',
                        fixed: 'left',
                        title: '序号'
                    }
                    , {
                        field: 'name',
                        title: '角色名称',
                        sort: true
                    }, {
                        field: 'code',
                        title: '角色代码',
                        sort: true
                    }, {
                        field: 'order_num',
                        title: '排序',
                        sort: true,
                        width: 85,
                    }, {
                        title: '状态',
                        width: 100,
                        templet: '#ID-table-status-switch'
                    }, {
                        title: '下一级',
                        width: 100,
                        align: 'center',
                        fixed: 'right',
                        toolbar: '#tableoption'
                    }, {
                        title: '权限分配',
                        width: 180,  // 增加宽度
                        align: 'center',
                        fixed: 'right',
                        toolbar: '#LAY-app-role-toolbar'
                    }]
                ],
                height: 'full-200',
                page: true,
                limit: 30,
                done: function (res) {
                }
            });
            // 统一事件处理 (按钮)
            util.on({
                Yjsearch: function () {
                    var keywords = $("#name").val();
                    table.reload('LAY-app-role-list', {
                        where: {
                            pid: pid,
                            name: keywords
                        },
                        page: {
                            curr: 1 //重新从第 1 页开始
                        }
                    });
                }
            });

            // 触发表格单元格工具事件
            table.on('tool(LAY-app-role-list)', function (obj) { // 双击 toolDouble
                var data = obj.data; // 获得当前行数据
                if (obj.event == 'next') {
                    const currentItem = data;
                    const newPath = parent_path ? `${parent_path},${currentItem.id}` : currentItem.id.toString();

                    // 更新路径变量和面包屑
                    parent_path = newPath;
                    breadcrumb.push({
                        id: currentItem.id,
                        name: currentItem.name,
                        path: newPath  // 保存完整路径
                    });

                    // 同步到隐藏字段
                    $("#pid").val(currentItem.id);
                    $("#parent_path").val(newPath);
                    pid = currentItem.id;
                    // 重新加载表格
                    table.reload('LAY-app-role-list', { where: { pid: pid } });

                    // 更新角色显示
                    updateBreadcrumb();
                }
                else if (obj.event === 'permission') {
                    var data = obj.data;
                    layer.open({
                        type: 1,
                        title: '权限分配 - ' + data.name,
                        content: $('#permissionTpl').html(),
                        area: ['80%', '80%'],
                        btn: ['确定', '取消'],
                        success: function (layero, index) {
                            // 加载权限数据
                            admin.req({
                                url: 'sysMenu/GetMenuList',
                                data: {
                                    page: 1,
                                    limit: 1000
                                },
                                // data: { roleId: data.id },
                                done: function (res) {
                                    if (res.successful) {
                                        /*获取当前角色拥有的菜单数据*/
                                        var menuData = res.data.data;
                                        // 加载权限数据
                                        admin.req({
                                            url: 'sysRole/getMenuIDByRoleID/' + data.id,
                                            done: function (res) {
                                                var checkedIds = res.data;
                                                // 使用示例
                                                const treeData = convertToTreeData(menuData, checkedIds);
                                                // 渲染权限树
                                                permissionTree = tree.render({
                                                    elem: '#permissionTree',
                                                    data: treeData,
                                                    showCheckbox: true,
                                                    checkStrictly: true,
                                                    id: 'permissionTree'

                                                });
                                            }
                                        });
                                    }
                                    else {
                                        main.msg_error('获取菜单数据失败!');
                                    }

                                }
                            });
                        },
                        yes: function (index, layero) {
                            // 获取选中的权限
                            var checkedData = tree.getChecked('permissionTree');
                            var permissionIds = getCheckedIds(checkedData);

                            // 提交保存
                            admin.req({
                                url: 'sysrole/SavePowerByRoleID',
                                type: 'POST',
                                contentType: 'application/json',
                                data: JSON.stringify({
                                    roleId: obj.data.id,
                                    menus: permissionIds.join(',')
                                }),
                                done: function (res) {
                                    layer.close(index);
                                    if (res.successful) {
                                        main.msg_success('保存成功！');
                                    } else {
                                        main.msg_error('保存失败！');
                                    }
                                }
                            });
                        }
                    });
                }

            });
            // 递归获取所有选中的ID
            function getCheckedIds(nodes) {
                var ids = [];
                nodes.forEach(function (node) {
                    if (node.checked) {
                        ids.push(node.id);
                    }
                    if (node.children) {
                        ids = ids.concat(getCheckedIds(node.children));
                    }
                });
                return ids;
            }
            /*将返回的菜单数据转换为tree需要的结构*/
            // 转换函数
            function convertToTreeData(menuList, checkedIds) {
                const nodeMap = new Map();
                const tree = [];

                // 创建节点映射并初始化
                menuList.forEach(item => {
                    nodeMap.set(item.id, {
                        id: item.id,
                        title: item.menuname,
                        pid: item.pid,
                        depth: item.depth,
                        children: [],
                        disabled: item.status === 1,  // 状态为1时禁用
                        checked: checkedIds.includes(item.id),//设置选中
                        spread: item.depth < 1  // 默认展开至第二级（depth从0开始）
                    });
                });

                // 构建树结构（支持异常数据）
                nodeMap.forEach(node => {
                    const parent = nodeMap.get(node.pid);
                    if (parent) {
                        // 找到父节点时建立关系
                        parent.children.push(node);
                    } else {
                        // 未找到父节点时作为根节点
                        if (!tree.find(n => n.id === node.id)) {
                            tree.push(node);
                        }
                    }
                });

                // 按排序号排序（需要确保所有层级都有order_num）
                function sortChildren(nodes) {
                    nodes.sort((a, b) => a.order_num - b.order_num);
                    nodes.forEach(node => {
                        if (node.children.length > 0) {
                            sortChildren(node.children);
                        }
                    });
                }
                sortChildren(tree);

                // 添加层级缩进（使用实际depth字段）
                function addVisualIndent(nodes) {
                    nodes.forEach(node => {
                        // 根据depth添加缩进（每级4个空格）
                        node.title = ' '.repeat(node.depth) + '├─ ' + node.title;
                        if (node.children.length > 0) {
                            addVisualIndent(node.children);
                        }
                    });
                }
                addVisualIndent(tree);

                return tree;
            }
            /*结束转换*/
            /* 导出弹出层 */
            $body.on("click", ".open-popup-export", function () {
                main.exportPopup();
            });

            /* 关闭弹出层 */
            $(".close-popup").click(function (e) {
                e.preventDefault();
                parent.layer.close(window.parent.layerIndex);
            });


        })
    </script>
</body>

</html>